#include <am.h>
#include <klib.h>
#include <klib-macros.h>
#include <stdarg.h>

#if !defined(__ISA_NATIVE__) || defined(__NATIVE_USE_KLIB__)
static const char num_table[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
char * num2str(long int num ,char*str,int flag){
    static char num_temp[32];
    int cnt=0; 
    char * temp=str;
    if (num < 0)
    {
        *str++ = '-';
        num = -num;
    }
    if (num < flag)
    {
        *str++ = num_table[num];

    }
    else {
        memset(num_temp, 0, sizeof(num_temp));
        while (num >= flag)
        {
            num_temp[cnt]=num_table[num%flag];
            num = num / flag;
            cnt++;
        }
        *str++ = num_table[num];
        for (size_t i = 0; i < cnt; i++)
        {
            *str++ = num_temp[cnt-i-1];
        }
        
    }
    return temp ;
}
int vsprintf(char *str, const char *format, va_list ap){
    char buf[0x80];
    int flag = 0;
    int i = 0;
    char *temp=buf ;
    char *st = str;
    while (*(format+i)){
        flag = 0;
        if (*(format+i) == '%')
        {
            i++;
            if (*(format+i) == 'l' || *(format+i) == 'L')
            {
                flag = 1;
                i++;
            }
            switch(*(format+i))
            {
                case 'd': /*整型*/
                {
                    memset(buf, 0, sizeof(buf));
                    if (flag)
                    {
                        __int64_t n = va_arg(ap, __int64_t);
                        temp = num2str(n,buf,10);
                    }
                    else {
                        int n = va_arg(ap, int);
                        temp = num2str(n,buf,10);
                    }
                    while (*temp) *st++ = *temp++;
                    break;
                }   
                case 'x': /*整型*/
                {
                    memset(buf, 0, sizeof(buf));
                    if (flag)
                    {
                        __int64_t n = va_arg(ap, __int64_t);
                        temp = num2str(n,buf,16);
                    }
                    else {
                        int n = va_arg(ap, int);
                        temp = num2str(n,buf,16);

                    }
                    while (*temp) *st++ = *temp++;
                    break;
                }   
                case 's': /*字符串*/
                {
                    char *s = va_arg(ap, char *);
                    while (*s) *st++ = *s++;
                    break;
                }
                case 'p':
                {
                    memset(buf, 0, sizeof(buf));
                    unsigned int n = va_arg(ap, int);
                    temp = num2str(n,buf,16);
                    while (*temp) *st++ = *temp++;
                    break;
                }
                default:
                    break;
            }
            i++;
            
        }
        else {
            *st++ = *(format+i);
            i++;
        }
    }
    *st = '\0';
    return st-str;
}
int sprintf(char *out, const char *fmt, ...) {
    va_list ap; va_start(ap,fmt);
	return vsprintf(out,fmt,ap);
}
static char temp[0x80];
int printf(const char *fmt, ...) {
	int counter=0;
    va_list ap;
    va_start(ap, fmt);
    counter = vsprintf(temp,fmt,ap);
    va_end(ap);
    putstr(temp);
    return counter;
}
int snprintf(char *out, size_t n, const char *fmt, ...) {
  panic("Not implemented");
}

int vsnprintf(char *out, size_t n, const char *fmt, va_list ap) {
  panic("Not implemented");
}

#endif